/* OpenSSL headers */
#include <stdio.h>
#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"

// 一个使用BIO的服务器端的例子
// 流程:
// <1> BIO_new_accept("5678") 建立一个accept bio
// <2> BIO_do_accept(abio)    "两次调用"该函数, 使之处于accepting 状态, 等待客户端连接
// <3> BIO *bio = BIO_pop(abio)          客户端连接到来之后, 使用该函数获得新进来的连接
// <4> 使用BIO_read和BIO_write来接收和发送数据.
int main(int argc, char *argv[]) {
  BIO *abio, *bio;
  char *wbuf = "this is a s -> c msg";
  char rbuf[128];
  memset(rbuf, 0, 128);

  /* Initializing OpenSSL */
  SSL_load_error_strings();
  ERR_load_BIO_strings();
  OpenSSL_add_all_algorithms();

  

  abio = BIO_new_accept("5678");
  if(abio == NULL)
  {
    printf("BIO_new_accept error\n");
    return -1;
  }

  // 需要调用两次BIO_do_accept
  // 第一次是设置accept的状态
  // 第二次是真正的接收client的连接
  if(BIO_do_accept(abio) <= 0)
  {
    printf("BIO_do_accept - 1 error\n");
    BIO_free_all(abio);
    return -1;
  }

  if(BIO_do_accept(abio) <= 0)
  {
    printf("BIO_do_accept - 1 error\n");
    BIO_free_all(abio);
    return -1;
  }
  printf("accepted the client connection\n");
  // 在accept之后使用BIO_pop获得新到的bio.
  bio = BIO_pop(abio);

  if(BIO_read(bio, rbuf, 128) <= 0) {
    printf("BIO_read error\n");
    BIO_free_all(abio);
    BIO_free_all(bio);
    return -1;
  }

  if(BIO_write(bio, wbuf, strlen(wbuf)) <= 0)
  {
    printf("BIO_write error\n");
    BIO_free_all(abio);
    BIO_free_all(bio);
    return -1;
  }

  printf("server# %s\n", rbuf);


  BIO_free_all(abio);
  BIO_free_all(bio);
  return 0;

}

